package com.framework.plm.sch.bs.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;

import com.framework.plm.bas.bs.IPlmBasBS;
import com.framework.plm.bas.cache.ICache;
import com.framework.plm.bas.exception.PlmBasException;
import com.framework.plm.bas.util.PlmBasConstant;
import com.framework.plm.bas.util.UtilDatetime;
import com.framework.plm.sch.bs.IPlmSchBS;
import com.framework.plm.sch.util.PlmSchConstant;
import com.framework.plm.sch.util.PlmSchFactory;
import com.framework.plm.sch.util.PlmSchManagerFactory;
import com.framework.plm.sch.vo.HpSchTaskVO;

public class PlmSchBSImpl implements IPlmSchBS {

	private IPlmBasBS plmBasBS;

	private PlmSchFactory plmSchFactory;

	private PlmSchManagerFactory plmSchManagerFactory;

	private String taskFlag;

	/**
	 * 缓存系统参数表
	 */
	private ICache cacheSchTask;

	public IPlmBasBS getPlmBasBS() {
		return plmBasBS;
	}

	public void setPlmBasBS(IPlmBasBS plmBasBS) {
		this.plmBasBS = plmBasBS;
	}

	public PlmSchFactory getPlmSchFactory() {
		return plmSchFactory;
	}

	public void setPlmSchFactory(PlmSchFactory plmSchFactory) {
		this.plmSchFactory = plmSchFactory;
	}

	public PlmSchManagerFactory getPlmSchManagerFactory() {
		return plmSchManagerFactory;
	}

	public void setPlmSchManagerFactory(PlmSchManagerFactory plmSchManagerFactory) {
		this.plmSchManagerFactory = plmSchManagerFactory;
	}

	public ICache getCacheSchTask() {
		return cacheSchTask;
	}

	public void setCacheSchTask(ICache cacheSchTask) {
		this.cacheSchTask = cacheSchTask;
	}

	public String getTaskFlag() {
		return taskFlag;
	}

	public void setTaskFlag(String taskFlag) {
		this.taskFlag = taskFlag;
	}

	public void doInit() {
		// 1. 缓存所有任务信息，key为id，value为HpSchTaskVO数组
//		doCacheAllTasks();
		try {
			plmSchFactory = plmSchManagerFactory.getInstance();
			Scheduler scheduler = plmSchFactory.getScheduler();
			// 2.启动任务
			List<Object> list = this.cacheSchTask.getKeys();
			for (Object keyo:list) {
				String key = keyo.toString();
				HpSchTaskVO obj = (HpSchTaskVO) this.cacheSchTask.get(key);
				if (obj.getTaskType().equals(taskFlag)) {
					this.startTask(key, scheduler);
				}
			}
			if(list!=null && list.size()>0){
				scheduler.start();
			}
		} catch (Exception e) {
			throw new PlmBasException(PlmSchConstant.MSG_0002, new Object[] {e.getMessage()});
		}
	}

	protected void doCacheAllTasks() {
		cacheSchTask.doInit();
	}

	/**
	 * 获得计划任务VO
	 * 
	 * @param jobCode
	 *            任务代码
	 * @return SchTaskVO
	 */
	public HpSchTaskVO queryTaskObj(String jobCode) {
		HpSchTaskVO vo = jobCode != null && jobCode.trim().length() > 0 ? (HpSchTaskVO) cacheSchTask.get(jobCode) : null;
		return vo;
	}

	/**
	 * 启动计划任务
	 * @param taskCode
	 *            任务代码
	 * @param scheduler
	 * @return void
	 */
	public void startTask(String taskCode) {
		HpSchTaskVO obj = (HpSchTaskVO) this.cacheSchTask.get(taskCode);
		try {
			Scheduler scheduler = plmSchFactory.getScheduler();
			Trigger trigger = scheduler.getTrigger(obj.getTaskCode(), obj.getGroupCode());
			if (trigger != null) {
				scheduler.pauseTrigger(obj.getTaskCode(), obj.getGroupCode());
				scheduler.unscheduleJob(obj.getTaskCode(), obj.getGroupCode());
				scheduler.deleteJob(obj.getTaskCode(), obj.getGroupCode());
			}
			startTask(obj.getTaskCode(), scheduler);
			if (!scheduler.isShutdown()) {
				scheduler.start();
			}
		} catch (Exception e) {
			throw new PlmBasException(PlmSchConstant.MSG_0001, new Object[] { obj.getTaskName() }, e);
		}
	}

	/**
	 * 启动计划任务
	 * 
	 * @param taskCode
	 *            任务代码
	 * @param scheduler
	 * @return void
	 */
	private void startTask(String taskCode, Scheduler scheduler) {
		HpSchTaskVO obj = (HpSchTaskVO) this.cacheSchTask.get(taskCode);
		try {
			JobDetail jobDetail = new JobDetail(obj.getTaskCode(), obj.getGroupCode(), Class.forName(obj.getExecClass()));
			// 判断是否可运行
			if (obj.getCanExec().equals(PlmBasConstant.STOP_FLAG)) {
				return;
			}
			// 判断是执行方式
			if (obj.getExecMode().equals(PlmBasConstant.USED_FLAG)) {
				// 定期执行
				SimpleTrigger simpleTrigger = new SimpleTrigger(obj.getTaskCode(), obj.getGroupCode());
				if (StringUtils.isNotBlank(obj.getRepeatTimes()) && Integer.parseInt(obj.getRepeatTimes()) > 0) {
					simpleTrigger.setRepeatCount(Integer.parseInt(obj.getRepeatTimes()));
				}
				if (StringUtils.isNotBlank(obj.getRepeatInterval()) && Integer.parseInt(obj.getRepeatInterval()) > 0) {
					simpleTrigger.setRepeatInterval(Integer.parseInt(obj.getRepeatInterval()));
				}
				Date date = UtilDatetime.toDate(obj.getStartTime());
				if (date != null) {
					simpleTrigger.setStartTime(date);
				}
				date = UtilDatetime.toDate(obj.getEndTime());
				if (date != null) {
					simpleTrigger.setEndTime(date);
				}
				// start delay
				if (StringUtils.isNotBlank(obj.getFirstDelay()) && Long.parseLong(obj.getFirstDelay()) > 0) {
					long lstartTime = obj.getStartTime() == null ? (System.currentTimeMillis() + Long.parseLong(obj.getFirstDelay()))
							: (simpleTrigger.getStartTime().getTime() + Long.parseLong(obj.getFirstDelay()));
					simpleTrigger.setStartTime(new Date(lstartTime));
				}
				scheduler.scheduleJob(jobDetail, simpleTrigger);
			} else {
				CronTrigger cronTrigger = new CronTrigger(obj.getTaskCode(), obj.getGroupCode());
				if (StringUtils.isNotBlank(obj.getTermExpress())) {
					cronTrigger.setCronExpression(obj.getTermExpress().trim());
				}
				Date date = UtilDatetime.toDate(obj.getStartTime());
				if (date != null) {
					cronTrigger.setStartTime(date);
				}
				date = UtilDatetime.toDate(obj.getEndTime());
				if (date != null) {
					cronTrigger.setEndTime(date);
				}
				scheduler.scheduleJob(jobDetail, cronTrigger);
			}
		} catch (Exception e) {
			throw new PlmBasException(PlmSchConstant.MSG_0000, new Object[] { obj.getTaskName() }, e);
		}

	}

	/**
	 * 停止计划任务
	 * 
	 * @param taskCode
	 *            任务代码
	 * @return void
	 */
	public void stopTask(String taskCode) {
		HpSchTaskVO vo = this.queryTaskObj(taskCode);
		try {
			Scheduler sch = getPlmSchFactory().getScheduler();
			sch.pauseTrigger(vo.getTaskCode(), vo.getGroupCode());
			sch.pauseJob(vo.getTaskCode(), vo.getGroupCode());
		} catch (Exception e) {
			throw new PlmBasException(PlmSchConstant.MSG_0001, new Object[] { vo.getTaskName() }, e);
		}
	}

	/**
	 * 更新计划任务状态
	 * 
	 * @param taskCode
	 *            任务代码
	 * @param canExec
	 *            是否可运行
	 * @return void
	 */
	public void txNewUpdateTaskExec(String taskCode, String canExec) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("taskCode", taskCode);
		map.put("canExec", canExec);
		this.getPlmBasBS().updateIbatisObj(PlmSchConstant.SQLID_UPDATE_TASK_CANEXEC, new Object[] { map });
	}

}
